package com.mallcai.bigdata.ladon.service.report.impl;

import com.cake.bigdata.starter.exception.category.BusinessException;
import com.cake.bigdata.starter.exception.error.CommonErrorCode;
import com.mallcai.bigdata.ladon.client.vo.ReportDataVO;
import com.mallcai.bigdata.ladon.client.param.ReportQueryParam;
import com.mallcai.bigdata.ladon.datasource.RunInfoResult;
import com.mallcai.bigdata.ladon.service.report.impl.handler.IReportQueryHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.StopWatch;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.OrderComparator;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author feixy
 * @version 1.0
 * @date 2019-07-19 20:29
 */
@Slf4j
@Component
public class ReportQueryPipeline implements ApplicationContextAware {

    private ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    private List<IReportQueryHandler> reportQueryHandlerList = new ArrayList<>();

    public ReportDataVO doQuery(ReportQueryParam reportParam, Map<String, Object> params) {
        StopWatch stopWatch = StopWatch.createStarted();
        try {
            ReportQueryContext context = new ReportQueryContext(this, reportParam, params);
            context.next();
            RunInfoResult<ReportDataVO> result = context.getResult();
            if (result == null) {
                throw new BusinessException(CommonErrorCode.EXCEPTION);
            }
            if (result.getError() != null) {
                Exception e = result.getError();
                if (!(e instanceof BusinessException)) {
                    e = new BusinessException(e);
                }
                throw (BusinessException) e;
            }
            return result.getData();
        } finally {
            log.info("报表[编码:{}]本次查询耗时:{}ms", reportParam.getReportCode(), stopWatch.getTime(TimeUnit.MILLISECONDS));
        }
    }


    public List<IReportQueryHandler> getReportQueryHandlerList() {
        return reportQueryHandlerList;
    }

    @PostConstruct
    private void init() {
        this.applicationContext.getBeansOfType(IReportQueryHandler.class)
                .values().stream()
                .sorted(OrderComparator.INSTANCE)
//                .peek(iReportQueryHandler -> System.out.println(iReportQueryHandler.getClass().getCanonicalName()))
                .forEach(this.reportQueryHandlerList::add);
    }
}
